package ferp.core.calc;

import ferp.core.game.Game;
import ferp.core.game.Settings;
import ferp.core.player.Player;

/**
 * User: olegs
 * Date: 20/05/11 18:29
 */
public class Sochi extends Calculator
{
  public Sochi()
  {
    // initialize Sochi's costs
    costs[0] = new int[] { 2,  2,  2,  2};
    costs[1] = new int[] { 4,  4,  4,  4};
    costs[2] = new int[] { 6,  6,  6,  6};
    costs[3] = new int[] { 8,  8,  8,  8};
    costs[4] = new int[] {10, 10, 10, 10};
  }

  @Override
  public boolean closed(Game g, Settings settings, Player p)
  {
    return g.getScore(p.id()).pool.current == settings.poolSize;
  }

  @Override
  public boolean over(Game g, Settings settings)
  {
    for (Player p : g.players())
      if (!closed(g, settings, p))
        return false;

    return true;
  }

  @Override
  public int getNormalizeFactor()
  {
    return 1;
  }

  @Override
  public void writeToPool(Game g, Settings settings, Player p, long value)
  {
    long left = settings.poolSize - g.getScore(p.id()).pool.current;
    if (left < value)
    {
      long aid = value - left;

      americanAid(g, settings, p, aid);

      // close player's pool
      super.writeToPool(g, settings, p, left);
    }
    else
      super.writeToPool(g, settings, p, value);
  }

  private void americanAid(Game g, Settings settings, Player from, long aid)
  {
    Player p2 = g.next(from);
    Player p3 = g.next(p2);

    // sort opponents by their pool, descending
    if (g.getScore(p2.id()).pool.current >= g.getScore(p3.id()).pool.current)
    {
      players[0] = p2;
      players[1] = p3;
    }
    else
    {
      players[0] = p3;
      players[1] = p2;
    }

    // write whists ten times of played game
    for (Player p : players)
    {
      long n = Math.min(settings.poolSize - g.getScore(p.id()).pool.current, aid);

      g.getScore(p.id()).pool.add(n);
      writeToWhists(g, from, p, 10 * n);
      aid -= n;
    }

    // if aid still > 0, then reduce from mountain
    if (aid > 0)
      writeToMountain(g, from, -Math.min(g.getScore(from.id()).mountain.current, aid));

    // the remaining aid (if any) is ignored
  }

  public static void main(String[] argv)
  {
/*
    Scanner scanner = new Scanner(System.in);
    int count = 0;
    StringBuilder sb = new StringBuilder(1024);

    Card.Set set = new Card.Set();

    for (int hash = 0; hash < 256; hash++)
    {
      set.reset();

      for (int card = Hand.first(hash); card != 0; card = Hand.next(hash, card))
        set.add(Card.card(card).rank());

      System.out.println(hash + " : " + set);

      boolean ok = false;

      while (!ok)
      {
        try
        {
          int tricks = Integer.valueOf(scanner.next());

          sb.append(tricks).append(',');

          if (++count == 10)
          {
            sb.append('\n');
            count = 0;
          }

          ok = true;
        }
        catch (NumberFormatException e)
        {
          System.err.println("Must be integer, please reenter");
        }
      }
    }

    System.out.println(sb);
*/
  }

  // players array for aid
  private final Player[] players = new Player[Game.PLAYERS - 1];
}

